package com.huaji.learn.repository;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.huaji.learn.helper.DBHelper;
import com.huaji.learn.model.AssociativeMemoryModel;
import com.huaji.learn.model.CornellModel;
import com.huaji.learn.model.EbbinghausModel;
import com.huaji.learn.model.FeynmanModel;
import com.huaji.learn.model.NoteModel;
import com.huaji.learn.model.constrants.DBConstraint;

import java.util.ArrayList;
import java.util.List;

/**
 * 笔记数据仓库
 *
 * 此类用来完成数据库的读取，所有笔记与数据库交互通过此类进行
 */
public class NoteRepository {
    /**
     * 数据库帮助类
     *
     * 用于操作数据库
     */
    private DBHelper helper;
    /**
     * 数据库实例
     */
    private SQLiteDatabase db;

    /**
     * 构造方法
     * @param context 安卓上下文
     */
    public NoteRepository(Context context){
        // 初始化帮助类，此时完成建表操作，若有表则跳过
        helper = new DBHelper(context);
        // 获取可以写的数据库实例
        db = helper.getWritableDatabase();
    }

    /**
     * 插入Note
     * @param model 要插入的Note
     * @return 更改的记录数
     */
    public long insertNote(NoteModel model) {
        // 将model的数据通过键值对的方式插入数据库
        ContentValues values = new ContentValues();
        values.put("CREATE_TIME", model.getCreateTime());
        values.put("CREATE_WEATHER", model.getCreateWeather());
        values.put("F_B_REMIND", model.getFeynman().isRemind() ? 1 : 0);
        values.put("F_B_REPEAT", model.getFeynman().isRepeat() ? 1 : 0);
        values.put("F_B_RETHINK", model.getFeynman().isRethink() ? 1 : 0);
        values.put("F_FEELINGS", model.getFeynman().getFeelings());
        values.put("F_FEYNMAN_COUNT", model.getFeynman().getFeynmanCount());
        values.put("F_REVIEW_COUNT", model.getFeynman().getReviewCount());
        values.put("E_DAY_LIST", model.getEbbinghaus().getReviewDayListStr());
        values.put("C_REDUCE", model.getCornell().getReduce());
        values.put("C_RECITE", model.getCornell().getRecite());
        values.put("C_RECORD", model.getCornell().getRecord());
        values.put("C_REFLECT", model.getCornell().getReflect());
        values.put("M_MEMORY", model.getAssociativeMemory().getMemory());

        return db.insert(DBConstraint.TABLE_NOTE, null, values);
    }

    /**
     * 删除指定的笔记
     * @param id 要删除的笔记ID
     * @return 更改的记录数
     */
    public long deleteNote(int id) {
        // 指定删除的条件，例如根据主键删除
        String whereClause = "id = ?";
        String[] whereArgs = {"" + id}; // 主键的值

        return db.delete(DBConstraint.TABLE_NOTE, whereClause, whereArgs);
    }

    /**
     * 修改笔记
     * @param model 笔记Model
     * @return 更改的记录数
     */
    public long updateNote(NoteModel model) {
        ContentValues values = new ContentValues();
        values.put("ID", model.getId());
        values.put("CREATE_TIME", model.getCreateTime());
        values.put("CREATE_WEATHER", model.getCreateWeather());
        values.put("F_B_REMIND", model.getFeynman().isRemind() ? 1 : 0);
        values.put("F_B_REPEAT", model.getFeynman().isRepeat() ? 1 : 0);
        values.put("F_B_RETHINK", model.getFeynman().isRethink() ? 1 : 0);
        values.put("F_FEELINGS", model.getFeynman().getFeelings());
        values.put("F_FEYNMAN_COUNT", model.getFeynman().getFeynmanCount());
        values.put("F_REVIEW_COUNT", model.getFeynman().getReviewCount());
        values.put("E_DAY_LIST", model.getEbbinghaus().getReviewDayListStr());
        values.put("C_REDUCE", model.getCornell().getReduce());
        values.put("C_RECITE", model.getCornell().getRecite());
        values.put("C_RECORD", model.getCornell().getRecord());
        values.put("C_REFLECT", model.getCornell().getReflect());
        values.put("M_MEMORY", model.getAssociativeMemory().getMemory());

        // 指定更新的条件，例如根据主键更新
        String whereClause = "id = ?";
        String[] whereArgs = {"" + model.getId()};

        return db.update(DBConstraint.TABLE_NOTE, values, whereClause, whereArgs);
    }

    /**
     * 获取所有笔记的列表
     * @return 所有笔记
     */
    @SuppressLint("Range")
    public List<NoteModel> queryAllNotes(){
        List<NoteModel> items = new ArrayList<>();
        Cursor cursor = db.query(DBConstraint.TABLE_NOTE, null, null, null, null, null, null);
        // 遍历 Cursor 获取查询结果
        while (cursor.moveToNext()) {
            NoteModel note = new NoteModel();
            note.setId(cursor.getInt(cursor.getColumnIndex("ID")));
            note.setCreateTime(cursor.getString(cursor.getColumnIndex("CREATE_TIME")));
            note.setCreateWeather(cursor.getString(cursor.getColumnIndex("CREATE_WEATHER")));

            FeynmanModel feynmanModel = new FeynmanModel();
            feynmanModel.setRemind(cursor.getInt(cursor.getColumnIndex("F_B_REMIND")) == 1);
            feynmanModel.setRepeat(cursor.getInt(cursor.getColumnIndex("F_B_REPEAT")) == 1);
            feynmanModel.setRethink(cursor.getInt(cursor.getColumnIndex("F_B_RETHINK")) == 1);
            feynmanModel.setFeelings(cursor.getString(cursor.getColumnIndex("F_FEELINGS")));
            feynmanModel.setFeynmanCount(cursor.getInt(cursor.getColumnIndex("F_FEYNMAN_COUNT")));
            feynmanModel.setReviewCount(cursor.getInt(cursor.getColumnIndex("F_REVIEW_COUNT")));
            note.setFeynman(feynmanModel);

            EbbinghausModel ebbinghausModel = new EbbinghausModel();
            ebbinghausModel.setReviewDayList(cursor.getString(cursor.getColumnIndex("E_DAY_LIST")));
            note.setEbbinghaus(ebbinghausModel);

            CornellModel cornellModel = new CornellModel();
            cornellModel.setReduce(cursor.getString(cursor.getColumnIndex("C_REDUCE")));
            cornellModel.setRecite(cursor.getString(cursor.getColumnIndex("C_RECITE")));
            cornellModel.setRecord(cursor.getString(cursor.getColumnIndex("C_RECORD")));
            cornellModel.setReflect(cursor.getString(cursor.getColumnIndex("C_REFLECT")));
            note.setCornell(cornellModel);

            AssociativeMemoryModel associativeMemoryModel = new AssociativeMemoryModel();
            associativeMemoryModel.setMemory(cursor.getString(cursor.getColumnIndex("M_MEMORY")));
            note.setAssociativeMemory(associativeMemoryModel);

            items.add(note);
        }

        cursor.close();
        return items;
    }

    /**
     * 通过ID查找笔记
     * @param id 要查询的ID
     * @return 查到的笔记
     */
    @SuppressLint("Range")
    public NoteModel queryNote(int id){
        NoteModel note = new NoteModel();
        String selection = "id = ?";
        String[] selectionArgs = {"" + id}; // 主键的值，这里假设查询主键为 1 的记录
        Cursor cursor = db.query(DBConstraint.TABLE_NOTE, null, selection, selectionArgs, null, null, null);

        while (cursor.moveToNext()) {
            note.setId(cursor.getInt(cursor.getColumnIndex("ID")));
            note.setCreateTime(cursor.getString(cursor.getColumnIndex("CREATE_TIME")));
            note.setCreateWeather(cursor.getString(cursor.getColumnIndex("CREATE_WEATHER")));

            FeynmanModel feynmanModel = new FeynmanModel();
            feynmanModel.setRemind(cursor.getInt(cursor.getColumnIndex("F_B_REMIND")) == 1);
            feynmanModel.setRepeat(cursor.getInt(cursor.getColumnIndex("F_B_REPEAT")) == 1);
            feynmanModel.setRethink(cursor.getInt(cursor.getColumnIndex("F_B_RETHINK")) == 1);
            feynmanModel.setFeelings(cursor.getString(cursor.getColumnIndex("F_FEELINGS")));
            feynmanModel.setFeynmanCount(cursor.getInt(cursor.getColumnIndex("F_FEYNMAN_COUNT")));
            feynmanModel.setReviewCount(cursor.getInt(cursor.getColumnIndex("F_REVIEW_COUNT")));
            note.setFeynman(feynmanModel);

            EbbinghausModel ebbinghausModel = new EbbinghausModel();
            ebbinghausModel.setReviewDayList(cursor.getString(cursor.getColumnIndex("E_DAY_LIST")));
            note.setEbbinghaus(ebbinghausModel);

            CornellModel cornellModel = new CornellModel();
            cornellModel.setReduce(cursor.getString(cursor.getColumnIndex("C_REDUCE")));
            cornellModel.setRecite(cursor.getString(cursor.getColumnIndex("C_RECITE")));
            cornellModel.setRecord(cursor.getString(cursor.getColumnIndex("C_RECORD")));
            cornellModel.setReflect(cursor.getString(cursor.getColumnIndex("C_REFLECT")));
            note.setCornell(cornellModel);

            AssociativeMemoryModel associativeMemoryModel = new AssociativeMemoryModel();
            associativeMemoryModel.setMemory(cursor.getString(cursor.getColumnIndex("M_MEMORY")));
            note.setAssociativeMemory(associativeMemoryModel);
        }

        cursor.close();

        return note;
    }

    /**
     * 查询笔记数量
     * @return 数量
     */
    public int queryNoteCount() {
        // 执行查询操作，只返回记录数量而不获取具体数据
        Cursor cursor = db.query(DBConstraint.TABLE_NOTE, null, null, null, null, null, null);

        int res = cursor.getCount();

        cursor.close();
        return res;
    }

    /**
     * 查询随机的笔记
     * @return 查到的笔记model
     */
    @SuppressLint("Range")
    public NoteModel queryNoteRandom() {
        String query = "SELECT * FROM " + DBConstraint.TABLE_NOTE + " ORDER BY RANDOM() LIMIT 1;";

        // 执行查询
        Cursor cursor = db.rawQuery(query, null);

        NoteModel note = new NoteModel();

        // 处理查询结果
        if (cursor.moveToFirst()) {
            note.setId(cursor.getInt(cursor.getColumnIndex("ID")));
            note.setCreateTime(cursor.getString(cursor.getColumnIndex("CREATE_TIME")));
            note.setCreateWeather(cursor.getString(cursor.getColumnIndex("CREATE_WEATHER")));

            FeynmanModel feynmanModel = new FeynmanModel();
            feynmanModel.setRemind(cursor.getInt(cursor.getColumnIndex("F_B_REMIND")) == 1);
            feynmanModel.setRepeat(cursor.getInt(cursor.getColumnIndex("F_B_REPEAT")) == 1);
            feynmanModel.setRethink(cursor.getInt(cursor.getColumnIndex("F_B_RETHINK")) == 1);
            feynmanModel.setFeelings(cursor.getString(cursor.getColumnIndex("F_FEELINGS")));
            feynmanModel.setFeynmanCount(cursor.getInt(cursor.getColumnIndex("F_FEYNMAN_COUNT")));
            feynmanModel.setReviewCount(cursor.getInt(cursor.getColumnIndex("F_REVIEW_COUNT")));
            note.setFeynman(feynmanModel);

            EbbinghausModel ebbinghausModel = new EbbinghausModel();
            ebbinghausModel.setReviewDayList(cursor.getString(cursor.getColumnIndex("E_DAY_LIST")));
            note.setEbbinghaus(ebbinghausModel);

            CornellModel cornellModel = new CornellModel();
            cornellModel.setReduce(cursor.getString(cursor.getColumnIndex("C_REDUCE")));
            cornellModel.setRecite(cursor.getString(cursor.getColumnIndex("C_RECITE")));
            cornellModel.setRecord(cursor.getString(cursor.getColumnIndex("C_RECORD")));
            cornellModel.setReflect(cursor.getString(cursor.getColumnIndex("C_REFLECT")));
            note.setCornell(cornellModel);

            AssociativeMemoryModel associativeMemoryModel = new AssociativeMemoryModel();
            associativeMemoryModel.setMemory(cursor.getString(cursor.getColumnIndex("M_MEMORY")));
            note.setAssociativeMemory(associativeMemoryModel);
        }

        return note;
    }

    /**
     * 清空数据
     */
    public void clearAllData() {
        String sql = "DELETE FROM " + DBConstraint.TABLE_NOTE;
        db.execSQL(sql);
    }

    /**
     * 执行SQL语句
     * @param sql 要执行的SQL语句
     */
    public void execSQL(String sql) {
        db.execSQL(sql);
    }

    /**
     * 关闭数据库连接
     */
    public void disconnect() {
        db.close();
    }
}
